/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package cong.javadanang.model.dao.impl;

import cong.javadanang.model.dao.QuestionDAO;
import cong.javadanang.model.entity.Answer;
import cong.javadanang.model.entity.Question;
import hibernate.HibernateUtil;
import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;

/**
 *
 * @author Pham
 */
public class QuestionDAOImpl implements QuestionDAO {

    private static QuestionDAOImpl questionDao;

    public static QuestionDAOImpl getInstance() {
        if (questionDao == null) {
            questionDao = new QuestionDAOImpl();
        }
        return questionDao;
    }
    private Session session;
    private Transaction ts;

    @Override
    public Question getQuestionById(int quesId) {
        Question question = null;
        session = HibernateUtil.getSessionFactory().openSession();
        try {
            ts = session.beginTransaction();
            question = (Question) session.get(Question.class, quesId);
            List<Answer> answers = session.createQuery("From Answer as a where a.question = :question")
                    .setParameter("question", question).list();
            question.setAnswers(answers);
            ts.commit();
        } catch (HibernateException e) {
            if (ts != null) {
                ts.rollback();
            }
            e.printStackTrace();
        } finally {
            session.close();
        }
        return question;
    }

    @Override
    public List<Question> getQuestions(int param) {
        session = HibernateUtil.getSessionFactory().openSession();
        List<Question> questions = null;
        try {
            ts = session.beginTransaction();
            Query query = session.createSQLQuery("CALL sp_GetQuestions(?)").addEntity(Question.class).setParameter(0, param);
            questions = query.list();
            for (Question question : questions) {
                List<Answer> answers = session.createQuery("From Answer as a where a.question = :question")
                        .setParameter("question", question).list();
                question.setAnswers(answers);
            }
            ts.commit();
        } catch (HibernateException e) {
            if (ts != null) {
                ts.rollback();
            }
            e.printStackTrace();
        } finally {
            session.close();
        }
        return questions;
    }

    @Override
    public List<Question> getListOfQuestion(int firstRow, int rowCount, String param) {
        session = HibernateUtil.getSessionFactory().openSession();
        List<Question> questions = null;
        try {
            ts = session.beginTransaction();
            Criteria criteria = session.createCriteria(Question.class);
            if (param != null) {
                switch (param) {
                    case "votes":
                        criteria.addOrder(Order.desc("vote"));
                        break;
                    case "enable":
                        criteria.add(Restrictions.eq("active", true));
                        break;
                    case "disable":
                        criteria.add(Restrictions.eq("active", false));
                        break;
                    default:
                        break;
                }
            }
            criteria.setFirstResult(firstRow);
            criteria.setMaxResults(rowCount);
            questions = criteria.list();
            for (Question question : questions) {
                List<Answer> answers = session.createQuery("From Answer as a where a.question = :question")
                        .setParameter("question", question).list();
                question.setAnswers(answers);
            }
            ts.commit();
        } catch (HibernateException e) {
            if (ts != null) {
                ts.rollback();
            }
            e.printStackTrace();
        } finally {
            session.close();
        }
        return questions;
    }

    @Override
    public boolean createQuestion(Question question) {
        session = HibernateUtil.getSessionFactory().openSession();
        try {
            ts = session.beginTransaction();
            session.save(question);
            ts.commit();
            return true;
        } catch (Exception e) {
            if (ts != null) {
                ts.rollback();
            }
            e.printStackTrace();
            return false;
        } finally {
            session.close();
        }
    }

    @Override
    public boolean updateQuestion(Question question) {
        session = HibernateUtil.getSessionFactory().openSession();
        try {
            ts = session.beginTransaction();
            session.update(question);
            ts.commit();
            return true;
        } catch (Exception e) {
            if (ts != null) {
                ts.rollback();
            }
            e.printStackTrace();
            return false;
        } finally {
            session.close();
        }
    }

    @Override
    public boolean updateVote(Question question) {
        boolean isCheck = false;
        session = HibernateUtil.getSessionFactory().openSession();
        try {
            ts = session.beginTransaction();
            String sql = "UPDATE Question as p set p.vote = ? WHERE p.questionId = ?";
            Query query = session.createQuery(sql);
            query.setParameter(0, question.getVote());
            query.setParameter(1, question.getQuestionId());
            query.executeUpdate();
            ts.commit();
            isCheck = true;
        } catch (HibernateException e) {
            if (ts != null) {
                ts.rollback();
            }
            e.printStackTrace();
        } finally {
            session.close();
        }
        return isCheck;
    }

    @Override
    public boolean updateViewCount(Question question) {
        boolean isCheck = false;
        session = HibernateUtil.getSessionFactory().openSession();
        try {
            ts = session.beginTransaction();
            String sql = "UPDATE Question as p set p.viewCount = ? WHERE p.questionId = ?";
            Query query = session.createQuery(sql);
            query.setParameter(0, question.getViewCount());
            query.setParameter(1, question.getQuestionId());
            query.executeUpdate();
            ts.commit();
            isCheck = true;
        } catch (HibernateException e) {
            if (ts != null) {
                ts.rollback();
            }
            e.printStackTrace();
        } finally {
            session.close();
        }
        return isCheck;
    }

    @Override
    public boolean deleteQuestion(Question question) {
        session = HibernateUtil.getSessionFactory().openSession();
        try {
            ts = session.beginTransaction();
            session.delete(question);
            ts.commit();
            return true;
        } catch (Exception e) {
            if (ts != null) {
                ts.rollback();
            }
            e.printStackTrace();
            return false;
        } finally {
            session.close();
        }
    }

    @Override
    public boolean restoreQuestion(Question question) {
        session = HibernateUtil.getSessionFactory().openSession();
        try {
            ts = session.beginTransaction();
            String sql = "UPDATE Question set active = true WHERE questionId = :questionId";
            Query query = session.createQuery(sql);
            query.setParameter("questionId", question.getQuestionId());
            query.executeUpdate();
            ts.commit();
            return true;
        } catch (HibernateException e) {
            if (ts != null) {
                ts.rollback();
            }
            e.printStackTrace();
            return false;
        } finally {
            session.close();
        }
    }

    @Override
    public boolean removeQuestion(Question question) {
        session = HibernateUtil.getSessionFactory().openSession();
        try {
            ts = session.beginTransaction();
            String sql = "UPDATE Question set active = false WHERE questionId = :questionId";
            Query query = session.createQuery(sql);
            query.setParameter("questionId", question.getQuestionId());
            query.executeUpdate();
            ts.commit();
            return true;
        } catch (HibernateException e) {
            if (ts != null) {
                ts.rollback();
            }
            e.printStackTrace();
            return false;
        } finally {
            session.close();
        }
    }

    @Override
    public List<Question> getQuestionByName(String name) {
        session = HibernateUtil.getSessionFactory().openSession();
        List<Question> questions = null;
        try {
            ts = session.beginTransaction();
            String sql = "FROM Question Where questionName=?";
            Query query = session.createQuery(sql);
            query.setParameter(0, name);
            questions = query.list();
            for (Question question : questions) {
                List<Answer> answers = session.createQuery("From Answer as a where a.question = :question")
                        .setParameter("question", question).list();
                question.setAnswers(answers);
            }
            ts.commit();
        } catch (HibernateException e) {
            if (ts != null) {
                ts.rollback();
            }
            e.printStackTrace();
        } finally {
            session.close();
        }
        return questions;
    }

    @Override
    public boolean checkExistQuestion(String questionName) {
        boolean isCheck = false;

        session = HibernateUtil.getSessionFactory().openSession();
        Transaction tx = null;
        try {
            tx = session.beginTransaction();
            String sql = "FROM Question as q WHERE q.questionName = ?";
            Query query = session.createQuery(sql);
            query.setParameter(0, questionName);
            if (query.list() != null && query.list().size() > 0) {
                isCheck = true;
            }
            tx.commit();
        } catch (HibernateException e) {
            if (tx != null) {
                tx.rollback();
            }
            e.printStackTrace();
            isCheck = false;
        } finally {
            session.close();
        }
        return isCheck;
    }

}
